package com.ytjj.qmyx.admin.service.impl;

import com.gexin.fastjson.JSON;
import com.gexin.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.ytjj.common.api.CommonPage;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.constants.CopyWriterConstant;
import com.ytjj.common.constants.im.ImRedisKeyConstant;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.CopyWriterConfigUtil;
import com.ytjj.common.utils.HttpClientUtil;
import com.ytjj.qmyx.admin.client.BankerClient;
import com.ytjj.qmyx.admin.config.SupplyApiConfig;
import com.ytjj.qmyx.admin.constants.SysConfigConstants;
import com.ytjj.qmyx.admin.dao.BankerDao;
import com.ytjj.qmyx.admin.dao.BankerLabelDao;
import com.ytjj.qmyx.admin.mapper.AdminMapper;
import com.ytjj.qmyx.admin.mapper.AdminRoleRelationMapper;
import com.ytjj.qmyx.admin.mapper.BankerRoleRelationMapper;
import com.ytjj.qmyx.admin.mapper.MenuMapper;
import com.ytjj.qmyx.admin.model.*;
import com.ytjj.qmyx.admin.model.banker.BankerListsDto;
import com.ytjj.qmyx.admin.model.request.AdminRequest;
import com.ytjj.qmyx.admin.model.request.BankerRequest;
import com.ytjj.qmyx.admin.model.request.BankerUpdatePutOnRequest;
import com.ytjj.qmyx.admin.model.request.UpdateRoleRequest;
import com.ytjj.qmyx.admin.model.response.BankerDataResponse;
import com.ytjj.qmyx.admin.model.response.BankerResponse;
import com.ytjj.qmyx.admin.service.AdminService;
import com.ytjj.qmyx.admin.service.MemberService;
import com.ytjj.qmyx.mall.mapper.BankerMapper;
import com.ytjj.qmyx.mall.mapper.SpecialBrandMapper;
import com.ytjj.qmyx.mall.model.Banker;
import com.ytjj.qmyx.mall.model.BankerSite;
import com.ytjj.qmyx.mall.model.MenuApi;
import com.ytjj.qmyx.mall.model.SpecialBrand;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@Slf4j
@Service
@RefreshScope
public class AdminServiceImpl implements AdminService {

    @Resource
    private AdminMapper adminMapper;

    @Resource
    private BankerMapper bankerMapper;

    @Resource
    private BankerDao bankerDao;

    @Resource
    private AdminRoleRelationMapper adminRoleRelationMapper;

    @Resource
    private BankerRoleRelationMapper bankerRoleRelationMapper;

    @Resource
    private MenuMapper menuMapper;

    @Resource
    private BankerLabelDao bankerLabelDao;

    @Resource
    private CopyWriterConfigUtil copyWriterConfigUtil;
    @Resource
    private SpecialBrandMapper specialBrandMapper;
    @Autowired
    private ProductServiceImpl productService;

    @Autowired
    private BankerClient bankerClient;

    @Value("${shiroConfigure.salt}")
    private String salt;

    @Value("${shiroConfigure.hashIterations}")
    private int hashIterations;
    //客服角色id
    @Value("${kefu.roleId:2}")
    private String kefuRoleId;
    @Value("${admin.role.bankerInfo:30,45,1}")
    private String attractInvestmentRoleId;//招商角色id

    @Resource
    private MemberService memberService;
    @Resource
    private RedisService redisService;

    @Resource
    private SupplyApiConfig supplyApiConfig;

    @Override
    public Admin getAdminStatus(String account) {
        AdminExample adminExample = new AdminExample();
        adminExample.createCriteria().andEmailEqualTo(account);
        List<Admin> admins = adminMapper.selectByExample(adminExample);
        if (admins != null && admins.size() > 0) {
            return admins.get(0);
        }
        return null;
    }

    @Override
    public Admin getAdminByEmail(String email) {
        AdminExample adminExample = new AdminExample();
        adminExample.createCriteria().andEmailEqualTo(email).andStatusEqualTo(SysConfigConstants.STATUS_1);
        List<Admin> admins = adminMapper.selectByExample(adminExample);
        if (admins != null && admins.size() > 0) {
            Admin admin = admins.get(0);
            List<Role> role = adminMapper.getRoleByEmail(email);
            if (!CollectionUtils.isEmpty(role)) {
                admin.setRoleCode(role.get(0).getRoleCode());
            }
            return admin;
        }
        return null;
    }

    @Override
    public List<Menu> getAdminMenuList() {
        return menuMapper.selectByExample(new MenuExample());
    }

    @Override
    public List<Role> getRoleByEmail(String email) {
        return adminMapper.getRoleByEmail(email);
    }


    @Override
    public List<Menu> getMenuAllByTel(String tel) {
        return adminMapper.getMenuAllByTel(tel);
    }

    @Override
    public CommonResult addAdmin(Admin admin) {
        String email = admin.getEmail();
        if (!email.contains("@")){
            email = email + "@qmyx.com";
            admin.setEmail(email);
        }

        // 查看此用户（根据邮箱判断）是否存在
        if (adminMapper.checkAdmined(admin.getEmail()) > 0) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.MAILBOX_HOMOLOGOUS_NUMBER_EXIST));
        }
        if (adminMapper.selectAdmins(admin.getCompellation()) > 0){
            throw new ApiException("该姓名已存在!");
        }
        if (StringUtils.isNotEmpty(admin.getTel()) && !CollectionUtils.isEmpty(adminMapper.selectAdminsByTel(admin.getTel()))){
            throw new ApiException("该手机号码已存在!");
        }
        //哈希+加盐+次数
        Md5Hash md5SaltIterateHash = new Md5Hash(admin.getPwd(), salt, hashIterations);
        admin.setPwd(md5SaltIterateHash.toString());
        admin.setStatus(SysConfigConstants.STATUS_1);
        admin.setCreateTime(new Date());
        adminMapper.insert(admin);
        int id = adminMapper.selectAdmin(admin.getCompellation());
        addAdminRole(admin.getRoleId(),id);
        return CommonResult.success();
    }

    @Override
    public int updateAdmin(Admin admin) {
        // 此处是修改密码的功能，暂时不需要
        Admin rawAdmin = adminMapper.selectByPrimaryKey(admin.getId());
        if (rawAdmin.getPwd().equals(admin.getPwd())) {
            admin.setPwd(null);
        } else {
            if (StringUtils.isBlank(admin.getPwd())) {
                admin.setPwd(null);
            } else {
                Md5Hash md5SaltIterateHash = new Md5Hash(admin.getPwd(), salt, hashIterations);
                admin.setPwd(md5SaltIterateHash.toString());
            }
        }
        String email = admin.getEmail();
        if (!email.contains("@")){
            email = email + "@qmyx.com";
            admin.setEmail(email);
        }
        // 查看此用户（根据邮箱判断）是否存在
        if (!CollectionUtils.isEmpty(adminMapper.checkAdminedByEmail(admin.getEmail()))
                && admin.getId().compareTo(adminMapper.checkAdminedByEmail(admin.getEmail()).get(0)) != 0) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.MAILBOX_HOMOLOGOUS_NUMBER_EXIST));
        }
        if (!CollectionUtils.isEmpty(adminMapper.selectAdminsByCompellation(admin.getCompellation()))
                && admin.getId().compareTo(adminMapper.selectAdminsByCompellation(admin.getCompellation()).get(0)) != 0){
            throw new ApiException("该姓名已存在!");
        }
        if (StringUtils.isNotEmpty(admin.getTel())
                && !CollectionUtils.isEmpty(adminMapper.selectAdminsByTel(admin.getTel()))
                && admin.getId().compareTo(adminMapper.selectAdminsByTel(admin.getTel()).get(0)) != 0){
            throw new ApiException("该手机号码已存在!");
        }
        int count = adminMapper.updateByPrimaryKeySelective(admin);
        if (null != admin.getRoleId()) {
            adminMapper.updateAdminRole(admin.getId(), admin.getRoleId());
        }
        // 删除后台缓存
        // adminCacheService.delAdmin(id);

        return count;
    }

    @Override
    public int deleteAdmins(Integer id) {
        adminRoleRelationMapper.deleteByAdminId(id);
        return adminMapper.deleteAdmin(id);
    }

    @Override
    public int deleteAdmin(Integer id) {
        return adminMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int updateStatus(Admin admin) {
        if (admin.getStatus() == SysConfigConstants.STATUS_1) {
            admin.setStatus(SysConfigConstants.STATUS_0);
        } else {
            admin.setStatus(SysConfigConstants.STATUS_1);
        }
        admin.setUpdateTime(new Date());
        return adminMapper.updateByPrimaryKeySelective(admin);
    }

    @Override
    public int checkAdmined(String tel) {
        return adminMapper.checkAdmined(tel);
    }

    @Override
    public Admin selectAdminById(Integer id) {
        return adminMapper.selectByPrimaryKey(id);
    }

    @Override
    public CommonPage<Admin> selectList(AdminRequest adminRequest) {
        PageHelper.startPage(adminRequest.getPageNum(), adminRequest.getPageSize());
        List<Admin> page = adminMapper.selectList(adminRequest);//.stream().filter(item -> !"admin".equals(item.getName())).collect(Collectors.toList());
        page.stream().forEach(item -> {
            String[] split = item.getEmail().split("@qmyx.com");
            String emailCut = "";
            for (String s : split) {
                emailCut = emailCut + s;
            }
            item.setEmailCut(emailCut);
        });
        return CommonPage.restPage(page);
    }

    @Override
    public int updateRole(UpdateRoleRequest updateRoleRequest) {
        List<Integer> roleIds = updateRoleRequest.getRoleIds();
        Integer id = updateRoleRequest.getId();
        int count = roleIds == null ? 0 : roleIds.size();
        // 删除之前角色
        AdminRoleRelationExample adminRoleRelationExample = new AdminRoleRelationExample();
        adminRoleRelationExample.createCriteria().andAdminIdEqualTo(id);
        adminRoleRelationMapper.deleteByExample(adminRoleRelationExample);
        if (!CollectionUtils.isEmpty(roleIds)) {
            List<AdminRoleRelation> list = new ArrayList<>();
            for (Integer roleId : roleIds) {
                AdminRoleRelation adminRoleRelation = new AdminRoleRelation();
                adminRoleRelation.setAdminId(id);
                adminRoleRelation.setRoleId(roleId);
                list.add(adminRoleRelation);
            }
            // 批量新增
            adminRoleRelationMapper.insertList(list);
        }
        // 删除缓存

        return count;
    }

    @Override
    public List<Role> getRoleListByAdminId(Integer adminId) {
        return adminRoleRelationMapper.getRoleListByAdminId(adminId);
    }

    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("1");list1.add("5");list1.add("30");
//        List<Integer> list2 = new ArrayList<>();
//        list2.add(2);list2.add(3);list2.add(30);
        String attractInvestmentRoleId = "2,3,4";
        List list2 = Arrays.asList(attractInvestmentRoleId.split(","));
        System.out.println(Collections.disjoint(list1, list2));
    }

    @Override
    public CommonPage<BankerDataResponse> bankerList(BankerRequest bankerRequest, Admin admin) {
        List<Role> roleList = getRoleListByAdminId(admin.getId());
        AtomicBoolean canSee = new AtomicBoolean(false);
        if (!CollectionUtils.isEmpty(roleList)) {
            List params = Arrays.asList(attractInvestmentRoleId.split(","));
            roleList.stream().map(Role::getId).collect(Collectors.toList());
            roleList.stream().forEach(item -> {
                if (params.contains(item.getId().toString())) {
                    canSee.set(true);
                }
            });
        }
        PageHelper.startPage(bankerRequest.getPageNum(), bankerRequest.getPageSize());
        List<BankerDataResponse> bankerDataResponseList = bankerDao.getBankerDataResponseList(bankerRequest);
        if(!CollectionUtils.isEmpty(bankerDataResponseList)) {
            for(BankerDataResponse bdr : bankerDataResponseList) {
                //供应商标签
                List<BankerLabel> bankerLabels = bankerLabelDao.selectByBankerId(bdr.getId());
                StringBuffer bankerLabelStr = new StringBuffer();
                List<Integer> bankerLabelIds = new ArrayList<>();
                if (!CollectionUtils.isEmpty(bankerLabels)){
                    bankerLabels.forEach(bankerLabel -> {
                        bankerLabelIds.add(bankerLabel.getBankerLabelId());
                        bankerLabelStr.append(bankerLabel.getBankerLabelName()).append(", ");
                    });
                    bdr.setBankerLabelList(bankerLabels);
                    bdr.setBankerLabelIds(bankerLabelIds);
                }
                List<BankerResponse> specialBrand = bankerDao.getSpecialBrand(bdr.getId());
                bdr.setBankerResponseList(specialBrand);
                if (null == bdr.getSaleNum() || bdr.getSaleNum().equals(0)) {
                    bdr.setBackRatio(BigDecimal.ZERO);
                }else if (null == bdr.getBackNum() || bdr.getBackNum().equals(0)) {
                    bdr.setBackRatio(BigDecimal.ZERO);
                }else {
                    BigDecimal backRatio = new BigDecimal(bdr.getBackNum()).divide(new BigDecimal(bdr.getSaleNum()), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                    bdr.setBackRatio(backRatio);
                }
                if (!canSee.get()) {
                    bdr.setSaleAmount(BigDecimal.ZERO);
                    bdr.setSaleNum(0);
                    bdr.setBackAmount(BigDecimal.ZERO);
                    bdr.setBackRatio(BigDecimal.ZERO);
                }
            }
        }
        return CommonPage.restPage(bankerDataResponseList);
    }

    @Override
    public CommonPage bankerLists(BankerRequest bankerRequest, Admin admin) {
        BankerListsDto bankerListsDto = new BankerListsDto();
        bankerListsDto.setBankerRequest(bankerRequest);
        bankerListsDto.setAdmin(admin);
        String resultJson = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/banker/list", JSONObject.toJSONString(bankerRequest), supplyApiConfig.getHeadsMap());
        CommonPage commonPage = JSONObject.parseObject(resultJson, CommonPage.class);
        return commonPage;
    }

    @Override
    public void updateHoliday(Integer id) {
        Banker banker = bankerMapper.selectByPrimaryKey(id);
        if(banker.getIsHoliday() == 0) {
            bankerDao.updateHoliday(id, 1);
        } else {
            bankerDao.updateHoliday(id, 0);
        }
    }

    @Override
    public Banker selectBankerById(Integer id) {
        return bankerMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<Role> getRoleListByBankerId(Integer bankerId) {
        return bankerDao.getRoleListByBankerId(bankerId);
    }

    @Override
    public int updateBankerRole(UpdateRoleRequest updateRoleRequest) {
        List<Integer> roleIds = updateRoleRequest.getRoleIds();
        Integer id = updateRoleRequest.getId();
        int count = roleIds == null ? 0 : roleIds.size();
        // 删除之前角色
        BankerRoleRelationExample bankerRoleRelationExample = new BankerRoleRelationExample();
        bankerRoleRelationExample.createCriteria().andBankerIdEqualTo(id);
        bankerRoleRelationMapper.deleteByExample(bankerRoleRelationExample);
        if (!CollectionUtils.isEmpty(roleIds)) {
            List<BankerRoleRelation> list = new ArrayList<>();
            for (Integer roleId : roleIds) {
                BankerRoleRelation bankerRoleRelation = new BankerRoleRelation();
                bankerRoleRelation.setBankerId(id);
                bankerRoleRelation.setRoleId(roleId);
                list.add(bankerRoleRelation);
            }
            // 批量新增
            bankerRoleRelationMapper.insertList(list);
        }
        return count;
    }

    @Override
    public Menu selectMenuByPId(String pId) {
        return menuMapper.selectByPrimaryKey(Integer.parseInt(pId));
    }

    @Override
    public void bankerPutaway(Integer id) {
        BankerSite bankerSite = bankerDao.getBankerSite(id);
        if (bankerSite == null) {
            throw new ApiException("供应商未完善官网信息，无法上架");
        }
        Banker banker = new Banker();
        banker.setId(id);
        banker.setStatus((byte) 1);
        bankerMapper.updateByPrimaryKeySelective(banker);
    }

    @Override
    public List<MenuApi> getMenuApiList(Integer roleId) {
       return adminMapper.getMenuApiByRoleId(roleId);
    }

    @Override
    public List<String> getApiCodeList(Integer roleId) {
        return adminMapper.getApiCodeList(roleId);
    }

    @Override
    public Banker addBanker(BankerRequest banker) {
        // 查看此供应商是否存在
        if (adminMapper.checkBankerName(banker.getName().trim()) > 0) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.NAME_EXIST));
        }
        if (adminMapper.checkBankered(banker.getTel()) > 0) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.NUMBER_EXIST));
        }
        //哈希+加盐+次数
        Md5Hash md5SaltIterateHash = new Md5Hash(banker.getPwd(), salt, hashIterations);
        banker.setPwd(md5SaltIterateHash.toString());
        banker.setCreateTime(new Date());
        banker.setStatus(SysConfigConstants.STATUS_1);
        banker.setAdminId(memberService.getAdmin().getId());
        banker.setAdminName(memberService.getAdmin().getName());

        Banker addBanker = new Banker();
        BeanUtils.copyProperties(banker, addBanker);
        bankerMapper.insertSelective(addBanker);

        //获取新增后的bankerId
        Integer bankerId = addBanker.getId();
        String specialIds = banker.getSpecialIds();
        if (StringUtils.isNotEmpty(specialIds)) {
            String[] specialIdStr = specialIds.split(",");
            for (String specialid : specialIdStr) {
                int id = Integer.valueOf(specialid);
                SpecialBrand specialBrand = new SpecialBrand();
                specialBrand.setSpecialId(id);
                specialBrand.setBankerId(bankerId);
                specialBrand.setStatus(1);
                specialBrand.setCreateTime(new Date());
                specialBrandMapper.insertSelective(specialBrand);
            }
        }

        return banker;
    }

    @Override
    public String newAddBanker(BankerRequest banker) {
        banker.setAdminId(memberService.getAdmin().getId());
        banker.setAdminName(memberService.getAdmin().getName());
        String json = JSON.toJSONString(banker);
        String resultJson = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/banker/addBanker", json, supplyApiConfig.getHeadsMap());
        return resultJson;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateBanker(BankerRequest banker) {
        banker.setUpdateTime(new Date());
        //密码赋null,逆向工程时密码不做修改
        banker.setPwd(null);
        banker.setAdminId(memberService.getAdmin().getId());
        banker.setAdminName(memberService.getAdmin().getName());

        String json = JSON.toJSONString(banker);
        String resultJson = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/banker/updateBanker", json, supplyApiConfig.getHeadsMap());
        return resultJson;
    }


    @Override
    public int deleteBanker(Integer id) {
        return bankerMapper.deleteByPrimaryKey(id);
    }

    @Override
    @Transactional
    public void updateStatusBanker(Integer id, Integer status, String msg) {
        Banker banker = new Banker();
        banker.setId(id);
        banker.setStatus((status.byteValue()));
        if (0 == status) {
            banker.setOffMsg(msg);
            banker.setOffTime(new Date());
        }else {
            banker.setOffMsg(null);
            banker.setOffTime(null);
        }
        bankerMapper.updateByPrimaryKeySelective(banker);

        if (0 == status) {
            //如果是停用供应商，则下架供应商下的：店铺、品牌和商品
            offBankerSite(id);
            offBankerProduct(id);
        }
    }

    @Override
    public String newUpdateStatusBanker(Integer id, Integer status, String msg) {
        Map map = new HashMap();
        map.put("id",String.valueOf(id));
        map.put("status",String.valueOf(status));
        map.put("msg",msg);
        String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/banker/updateStatusBanker", map, supplyApiConfig.getHeadsMap());
        return resultJson;
    }

    /**
     * 下架供应商商品
     * @param id
     */
    private void offBankerProduct(Integer id) {
        productService.updateProductStatusByBankerId(id, 2);
    }

    /**
     * 下架供应商店铺
     * @param id
     */
    private CommonResult offBankerSite(Integer id) {
        BankerUpdatePutOnRequest request = new BankerUpdatePutOnRequest();
        request.setBankerId(id);
        request.setStatus(0);
        CommonResult result = bankerClient.bankerSitePutOn(request);
        return result;
    }

    /**
     * 客服上线计时
     * @param adminId
     * @param email
     */
    @Override
    public void customerServiceTimeHandle(Integer adminId, String email) {
        //客服登录需要开始作在线计时
        //1.判断是否是客服角色
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String curDate = sdf.format(new Date());
        List<Role> roles = getRoleListByAdminId(adminId);
        List<Integer> roleIds = roles.stream().map(item -> item.getId()).collect(Collectors.toList());
        if (roleIds.contains(kefuRoleId)) {
            redisService.set(ImRedisKeyConstant.IM_ONLINE_SERVICE_TIME + curDate + ":" + email, String.valueOf(System.currentTimeMillis()));//设置客服登录时的时间
            redisService.expire(ImRedisKeyConstant.IM_ONLINE_SERVICE_TIME + curDate + ":" + email, 18 * 60 * 60);
        }
    }

    @Override
    public int adminId(String email) {
        return adminMapper.adminId(email);
    }

    @Override
    public int addAdminRole(Integer roleId, Integer adminId) {
        return adminMapper.addAdminRole(roleId,adminId);
    }

    @Override
    public int updateStatusById(Integer id, Integer status) {
        //查询该账号的角色是都开启
        int roleStatus = adminMapper.findRoleAdminById(id);
        //如果为开启,账号状态可以更改,否则直接返回
        if (1 == roleStatus) {
            return  adminMapper.updateStatusById(id,status);
        }
       return 0;
    }
}
